package com.xucia.persevere.jsponic;

import java.io.IOException;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.mozilla.javascript.Function;

import com.xucia.jsponic.data.GlobalData;
import com.xucia.jsponic.data.Persistable;
import com.xucia.jsponic.remote.ClientTransformationPlugin;
/**
 * Jsponic plugin to preprocess Persevere JavaScript to add debugging and performance enhancements
 * @author Kris Zyp
 *
 */
public class PerseverePlugin implements ClientTransformationPlugin{
	private static Map<Function,String> compilationCache = new WeakHashMap<Function,String>();
	public Entry<String,String> augmentJsponForFunction(Function function, boolean debugMode) {
		try {
			if (((Persistable) function).get("runAt").equals("server")) 
				return makePersevereEntry("function(){return persevere.rpc(this,arguments);}");
			final String compiled = compilationCache.get(function);
			if (compiled != null) {
				return makePersevereEntry(compiled);
			}
			String newCompiled;
			Object lang = function.get("lang", function);
			boolean js17 = "js17".equals(lang) || "autosavejs17".equals(lang);
			boolean setters = !(lang instanceof String && ((String)lang).startsWith("js"));
			boolean getters = !("js".equals(lang) || "js15".equals(lang));
			try {
				compilationCache.put(function,newCompiled = com.xucia.strands.Compiler.compileString((String) function.get(GlobalData.FUNCTION_METHOD_FIELD,function),getters,setters,true,debugMode,js17,((Persistable) function).getId().toString()));
			} catch (ClassCastException e) {
				throw new RuntimeException(e); // how does this happen?
			}
			return makePersevereEntry(newCompiled);
		} catch (IOException e) {			
			throw new RuntimeException(e);
		}
	}
	private Entry<String,String> makePersevereEntry(final String compiledCode) {
		return new Entry<String,String>() {
			public String getValue() {
				return compiledCode;
			}
			public String getKey() {
				return "psv15";
			}
			public String setValue(String value) {
				throw new UnsupportedOperationException();
			}
		};
	}
}
